#include "TileNode.h"
#include "Map.h"

namespace pathfinding
{
	TileNode::TileNode() :_coords(0, 0), _map(nullptr)
	{

	}

	TileNode::TileNode( Map* map, int x, int y ) : _map(map), _coords(x, y)
	{
		_tile = map->getTile(_coords.x, _coords.y);
	}

	float TileNode::GoalDistanceEstimate( const TileNode& goal ) const
	{
		return static_cast<float>(abs(_coords.x - goal._coords.x) + abs(_coords.y - goal._coords.y));
	}

	bool TileNode::IsGoal( const TileNode& nodeGoal ) const
	{
		return IsSameState( nodeGoal );
	}

	bool TileNode::IsSameState( const TileNode& other ) const
	{
		return _coords == other._coords;
	}

	float TileNode::GetCost( const TileNode& other ) const
	{
		return 1.0f;
	}

	bool TileNode::GetSuccessors( AStarSearch<TileNode>* search, const TileNode* parentNode ) const
	{
		static const int tile_offsets[4][2] = {{0,1}, {1,0}, {0,-1}, {-1,0}};

		for (unsigned int i = 0; i < 4; ++i)
		{
			IntPoint tile(_coords.x + tile_offsets[i][0], _coords.y + tile_offsets[i][1]);
			if (_map->getRect().hitTest(tile.x, tile.y) && _map->isPassable(tile.x, tile.y) && !(parentNode != nullptr && parentNode->_coords == tile))
			{
				TileNode newNode(_map, tile.x, tile.y);
				search->AddSuccessor(newNode);
			}
		}
		return true;
	}

	const IntPoint& TileNode::getTileCoords() const
	{
		return _coords;
	}

}